package com.yyq.bigexport.util.export;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.thread.NamedThreadFactory;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yyq.bigexport.service.ExportService;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.concurrent.*;

@Slf4j
public class ExcelExportTask implements Runnable {
    private String fileName;
    private Integer sheetNo;
    private ExportService exportService;
    private LambdaQueryWrapper queryWrapper;
    private Integer pageBeginIndex;
    private Integer pageEndIndex;
    private Integer pageSize;
    private CountDownLatch countDownLatch;
    private Class<?> clazz;

    private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(5,
            10,
            30,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(),
            new NamedThreadFactory("export-pool-",false));
    public ExcelExportTask(String fileName, Integer sheetNo, ExportService exportService, LambdaQueryWrapper queryWrapper, Integer pageBeginIndex, Integer pageEndIndex, Integer pageSize, CountDownLatch countDownLatch, Class<?> clazz) {
        this.fileName = fileName;
        this.sheetNo = sheetNo;
        this.exportService = exportService;
        this.queryWrapper = queryWrapper;
        this.pageBeginIndex = pageBeginIndex;
        this.pageEndIndex = pageEndIndex;
        this.pageSize = pageSize;
        this.countDownLatch = countDownLatch;
        this.clazz = clazz;
    }

    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        log.info("线程{}开始写入文件", threadName);
        //创建目录
        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        ExecutorCompletionService completionService = new ExecutorCompletionService<>(executorService);
        //创建流
        ExcelWriter excelWriter = EasyExcel.write(fileName).excelType(ExcelTypeEnum.XLSX).build();
        try {
            while (pageBeginIndex <= pageEndIndex) {
                long startTime = System.currentTimeMillis();
                log.info("线程{}正在查询第{}页数据", threadName, pageBeginIndex);
                //查数据
                IPage page = exportService.pageList(pageBeginIndex, pageSize, queryWrapper);
                // 写入数据
                log.info("线程{}正在写入数据{}条", threadName, page.getRecords().size());
                excelWriter.write(page.getRecords(), EasyExcel.writerSheet(String.format("sheet%d", sheetNo + 1)).head(clazz).build());
                log.info("线程{}写入完成", threadName);
                //循环查询写入
                pageBeginIndex++;
                log.info("线程{}导出数据完成，时间：{}", threadName,(System.currentTimeMillis() - startTime));
            }
        } finally {
            //任务完成后关闭流
            IoUtil.close(excelWriter);
            // 计数器减1
            countDownLatch.countDown();
        }
    }

}